/******************************************************************************
 * Product: Adempiere ERP & CRM Smart Business Solution                        *
 * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved.                *
 * This program is free software; you can redistribute it and/or modify it    *
 * under the terms version 2 of the GNU General Public License as published   *
 * by the Free Software Foundation. This program is distributed in the hope   *
 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.           *
 * See the GNU General Public License for more details.                       *
 * You should have received a copy of the GNU General Public License along    *
 * with this program; if not, write to the Free Software Foundation, Inc.,    *
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.                     *
 * For the text or an alternative of this public license, you may reach us    *
 * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA        *
 * or via info@compiere.org or http://www.compiere.org/license.html           *
 *****************************************************************************/
package org.adempiere.apps.form;

import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.VetoableChangeListener;
import java.sql.*;
import java.util.*;
import java.util.List;
import java.util.logging.*;
import java.math.*;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.basic.BasicInternalFrameTitlePane.RestoreAction;
import javax.swing.table.*;

import org.adempiere.model.MBarcodeTrx;
import org.adempiere.model.MBarcodeTrxLine;
import org.adempiere.model.MLoading;
import org.adempiere.model.MLoadingLine;
import org.compiere.apps.*;
import org.compiere.apps.form.FormFrame;
import org.compiere.apps.form.FormPanel;
import org.compiere.grid.ed.*;
import org.compiere.minigrid.*;
import org.compiere.model.*;
import org.compiere.swing.*;
import org.compiere.util.*;
import org.python.modules.newmodule;

import com.jhlabs.math.SCNoise;
import com.sun.jndi.url.corbaname.corbanameURLContextFactory;
/**
 *  Barcode Transaction Form Out
 *
 *  @author  Shindu
 *  @version 1.1
 *  @since May 2013
 */


public class BarcodeTransactionOut extends CPanel
	implements FormPanel, ActionListener, VetoableChangeListener
{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 121224L;

	/**
	 *	Initialize Panel
	 *  @param WindowNo window
	 *  @param frame frame
	 */
	public void init (int WindowNo, FormFrame frame)
	{
		//
		Env.setContext(Env.getCtx(), WindowNo, "IsSOTrx", "Y");
		log.info(frame.toString());
		p_WindowNo = WindowNo;
		m_frame = frame;
		m_frame.setMaximize(true);
			
		try
		{
			//
			MClientInfo info=MClientInfo.get(Env.getCtx());
			retailCode= info.getRetailPack_Code();
			fullCode=info.getFullPack_Code();
			lenUPC=info.getUPC_Len();
			//
			dynInit();
			jbInit();			
			confirmPanel.addActionListener(this);
			confirmPanel.setOKVisible(false);
			//  Set status
			statusBar.setStatusDB("");
			//tableChanged(null);
			p_initOK = true;
		}
		catch(Exception e)
		{
			log.log(Level.SEVERE, "", e);
			p_initOK = false;
		}
		//AEnv.positionCenterWindow(Env.getWindow(p_WindowNo), this);
	}	//	init
	
	
	
	/** Window No               */
	int      p_WindowNo;
	FormFrame 	m_frame;
	/** Model Tab               */
	//protected GridTab         		p_mTab;

	boolean p_initOK = false;
	boolean	isSOTrx=true;
	int totalLines;
	String retailCode, fullCode;
	int lenUPC;
	int C_Uom_ID;
	String UOM;

	/** Loaded Order            */
	/**	Logger			*/
	CLogger 		log = CLogger.getCLogger(getClass());
	/**	Static Logger	*/
	//
	private CPanel parameterPanel = new CPanel();
	private BorderLayout parameterLayout = new BorderLayout();
	private CPanel parameterStdPanel = new CPanel();	
	private GridBagLayout parameterStdLayout = new GridBagLayout();
	private JScrollPane dataPane = new JScrollPane();
	private CPanel southPanel = new CPanel();
	private BorderLayout southLayout = new BorderLayout();
	private ConfirmPanel confirmPanel = new ConfirmPanel(true);
	private StatusBar statusBar = new StatusBar();
	//
	private MiniTable dataTable = new MiniTable();
	//
	private JLabel bPartnerLabel = new JLabel();	
	private VLookup bPartnerField;
	private JLabel cOrderLabel = new JLabel();	
	private VLookup cOrderField;
	private JLabel locatorLabel = new JLabel();
	private VLocator locatorField;
	private JLabel docTypeLabel = new JLabel();
	private VLookup docTypeField; 
	private JLabel barcodeLabel = new JLabel();
	private CTextField barcodePN = new CTextField();
	private JLabel infoInserted = new JLabel();
	//
	private VCheckBox isEceran = new VCheckBox();
	private VCheckBox isGenerated = new VCheckBox();
	
	public static final String SELECT_ALL = "SelectAll";
	
	Vector<Vector<Object>> data = new Vector<Vector<Object>>();
	Vector<String> dataPN = new Vector<String>();
	//objmodel
	MBarcodeTrx barcodetrx;
	
	//MInOut iohdr;
    
	/**
	 * Set Lookup
	 * @throws Exception
	 */
	protected void initLookup () throws Exception
	{
		//  load BPartner
		int AD_Column_ID = 3795;        //  All
		MLookup lookup = MLookupFactory.get (Env.getCtx(), p_WindowNo, 0, AD_Column_ID, DisplayType.Search);
		bPartnerField = new VLookup ("C_BPartner_ID", true, false, true, lookup);
		//order
		AD_Column_ID=3809;
		lookup = MLookupFactory.get (Env.getCtx(), p_WindowNo, 0, AD_Column_ID, DisplayType.Search);
		cOrderField = new VLookup ("C_Order_ID", true, false, true, lookup);
		//load doc type
		AD_Column_ID=3792;
		lookup = MLookupFactory.get(Env.getCtx(), p_WindowNo, 0, AD_Column_ID, DisplayType.Table);
		docTypeField=new VLookup("C_DocType_ID", true, false, true, lookup);
		//Locator		
		MLocatorLookup locator = new MLocatorLookup(Env.getCtx(), p_WindowNo);
		locatorField = new VLocator ("M_Locator_ID", true, false, true,	locator, p_WindowNo);		
		int M_Warehouse_ID = Env.getContextAsInt(Env.getCtx(), "M_Warehouse_ID");		
		locatorField.setValue(MWarehouse.get(Env.getCtx(), M_Warehouse_ID).getDefaultLocator().getM_Locator_ID());
		//
				
	}   //  initBPartner
	
	
	/**
	 *  Static Init
	 *  @throws Exception
	 */
	private void jbInit() throws Exception
	{
		Font boldFont = new Font(getFont().getName(), Font.BOLD, 12);
		parameterPanel.setLayout(parameterLayout);
		parameterStdPanel.setLayout(parameterStdLayout);
		//
		locatorLabel.setText(Msg.translate(Env.getCtx(), "M_Locator_ID"));
		bPartnerLabel.setText(Msg.translate(Env.getCtx(), "C_BPartner_ID"));
		docTypeLabel.setText(Msg.translate(Env.getCtx(), "C_DocType_ID"));
		cOrderLabel.setText(Msg.translate(Env.getCtx(), "C_Order_ID"));
        //
        isGenerated.setText(Msg.translate(Env.getCtx(), "IsGeneratedInOut"));
        isGenerated.setReadWrite(false);
        isEceran.setText(Msg.translate(Env.getCtx(), "IsEceran"));
        isEceran.setReadWrite(false);
        //
        barcodeLabel.setText("SCAN BARCODE");
        barcodeLabel.setFont(boldFont);
        barcodeLabel.setForeground(Color.BLUE);
        barcodePN.setFont(boldFont);
        barcodePN.setForeground(Color.BLUE);
        //
        infoInserted.setForeground(Color.BLUE);
        //
		locatorField.setMandatory(true);
		bPartnerField.setMandatory(true);
		cOrderField.setMandatory(true);
		docTypeField.setMandatory(true);
		//
        resetValue();
		//
		m_frame.getContentPane().add(parameterPanel, BorderLayout.NORTH);
		
		parameterPanel.add(parameterStdPanel, BorderLayout.CENTER);
		//Locator
        parameterStdPanel.add(locatorLabel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
                ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0));        
                    m_frame.getContentPane().add(dataPane, BorderLayout.CENTER);
        parameterStdPanel.add(locatorField, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0
               ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0));        
                    m_frame.getContentPane().add(dataPane, BorderLayout.CENTER);
        //Bpartner
       parameterStdPanel.add(bPartnerLabel, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0
                			,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
       parameterStdPanel.add(bPartnerField, new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0
                				,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0));
       //Order
       parameterStdPanel.add(cOrderLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0
   			,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
       parameterStdPanel.add(cOrderField, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0
   				,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0));

       //Doc type
       
       parameterStdPanel.add(docTypeLabel, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0
   			,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
       parameterStdPanel.add(docTypeField, new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0
   				,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0));
		//Eceran
        parameterStdPanel.add(isEceran,  new GridBagConstraints(2, 2, 1, 1, 0.0, 0.0
    			,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0));
		//
        parameterStdPanel.add(barcodeLabel, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0
            ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0));        
            	m_frame.getContentPane().add(dataPane, BorderLayout.CENTER);                    
        parameterStdPanel.add(barcodePN, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0));        
            	m_frame.getContentPane().add(dataPane, BorderLayout.CENTER);          	
        parameterStdPanel.add(infoInserted, new GridBagConstraints(2, 3, 1, 1, 0.0, 0.0
             ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0));        
              	m_frame.getContentPane().add(dataPane, BorderLayout.CENTER);
        //
                    
		dataPane.getViewport().add(dataTable, null);
		
		//
 		//
		// @Trifon
		AppsAction selectAllAction = new AppsAction (SELECT_ALL, KeyStroke.getKeyStroke(KeyEvent.VK_A, java.awt.event.InputEvent.ALT_MASK), null);
		
		CButton selectAllButton = (CButton)selectAllAction.getButton();
		selectAllButton.setMargin(new Insets (0, 10, 0, 10));
		selectAllButton.setDefaultCapable(true);
		//
		selectAllButton.addActionListener(this);
		barcodePN.addActionListener(this);
		bPartnerField.addVetoableChangeListener(this);
		cOrderField.addVetoableChangeListener(this);
		//
		m_frame.getContentPane().add(southPanel, BorderLayout.SOUTH);
		southPanel.setLayout(southLayout);
		southPanel.add(confirmPanel, BorderLayout.CENTER);
		m_frame.getContentPane().add(southPanel, BorderLayout.SOUTH);
		southPanel.setLayout(southLayout);
		southPanel.add(confirmPanel, BorderLayout.CENTER);
		southPanel.add(statusBar, BorderLayout.SOUTH);	   
	}   //  jbInit

	/**
	 * 	Dispose
	 */
	public void dispose()
	{
		if (m_frame != null)
			m_frame.dispose();
		m_frame = null;
	}	//	dispose

	/**
	 *  Dynamic Init (prepare dynamic fields)
	 *  @throws Exception if Lookups cannot be initialized
	 */
	private void dynInit() throws Exception
	{
		
		log.config("");
		//  load Locator
		
		initLookup();
		//  Translation
		statusBar.setStatusLine("Ready");
		statusBar.setStatusDB("-");

	}   //  dynInit

	/**
	 *  Vetoable Change Listener.
	 *  - Business Partner
	 *  - Order 
	 *  @param e event
	 */
	public void vetoableChange (PropertyChangeEvent e)
	{
		String name = e.getPropertyName();
		Object value = e.getNewValue();
		log.config(name + "=" + value);
		if (value == null)
			return;

		if (name.equals("C_BPartner_ID")){
			Env.setContext(Env.getCtx(), p_WindowNo, "C_BPartner_ID", (Integer) value);
			cOrderField.setValue(null);
			data.clear();
			loadTableOIS(data);
		}else if(name.equals("C_Order_ID")){
			loadOrderLines((Integer) value);
		}
		

	}   //  vetoableChange
	
	/**************************************************************************
	 *  Action Listener.
	 *  @param e event
	 */
	public void actionPerformed(ActionEvent e)
	{
		boolean isError=false;
		if (e.getSource().equals(barcodePN)){
			infoInserted.setText("");
			if (barcodePN.getValue().toString().length()!=lenUPC+1){
				ADialog.warn(p_WindowNo, this, "", "Barcode invalid format!");
				barcodePN.requestFocus();
				isError=true;			
			}else
			if(locatorField.getValue()==null){
				ADialog.warn(p_WindowNo, this, "", "Locator is mandatory!");
				locatorField.requestFocus();
				isError=true;		
			}else
			if (cOrderField.getValue()==null){
				ADialog.warn(p_WindowNo, this,"", "Sales order is mandatory!");
				cOrderField.requestFocus();
				isError=true;
			}else
			if (docTypeField.getValue()==null){
				ADialog.warn(p_WindowNo, this,"", "Document type is mandatory!");
				docTypeField.requestFocus();
				isError=true;
			}
			if (!isError){
				String trxName=Trx.createTrxName();
				String msg = barcodeScan(trxName);
				if (msg.equals("")){		
					statusBar.setStatusDB("Scaned!");
					Trx.get(trxName, false).commit();
				}else{					
					ADialog.warn(p_WindowNo, this, "", msg);
					Trx.get(trxName, false).rollback();
					statusBar.setStatusDB(msg);
				}
				barcodePN.requestFocus();				
			}
			barcodePN.setText("");
		}else if(e.getActionCommand().equals(ConfirmPanel.A_OK)){
			//
			if (!ADialog.ask(p_WindowNo, this,"SaveChanges?" )){
				return;
			}
			if (barcodetrx!=null){
				MInOut result=barcodetrx.generateMInOut();
				if (result!=null){
					ADialog.info(p_WindowNo, this, "", "Generated Shipem: " + result.getDocumentNo() + 
							"\r\nBarcode: " + barcodetrx.getM_BarcodeTrx_ID());					
					enableHeader(true);
					resetValue();
					data.clear();
					loadTableOIS(data);					
				}
			}
			//			
		}else if(e.getActionCommand().equals(ConfirmPanel.A_CANCEL)){
			if (ADialog.ask(p_WindowNo, this,"Close","Are you sure?" )){
				dispose();
			}			
		}else{
			System.out.println("Barcode Scan.Other action: " +  e.getActionCommand());
		}
	}   //  actionPerformed
	
	/**
	 * Reset value
	 */
	private void resetValue(){
		barcodePN.setText("");
		infoInserted.setText(Msg.getMsg(Env.getCtx(), "NotFound"));
		isEceran.setSelected(false);
		isGenerated.setSelected(false);		
		totalLines=0;
		barcodetrx=null;
	}
	
	private String[] parseBarcode(String BarcodeText){
		BarcodeText=BarcodeText.trim();
		String [] result = new String[2];
		result[0]=BarcodeText.substring(0, lenUPC);
		result[1]=BarcodeText.substring(lenUPC);
		return result;
	}
	
		
	/**
	 * Do barcode scan
	 * @param trxName
	 * @return
	 */
	private String barcodeScan(String trxName) {
		// Get produk
		String[] barcode = parseBarcode(barcodePN.getText());
		if (!(barcode[1].equalsIgnoreCase(fullCode) || barcode[1].equalsIgnoreCase(retailCode))){
			return "Invalid barcode string";
		}
		infoInserted.setText("");
		String result = "";
		String sql = "SELECT M_Product_ID FROM M_Product WHERE UPC = ?";
		int M_Product_ID = 0;
		try {
			PreparedStatement pstmt = DB.prepareStatement(sql, trxName);
			pstmt.setString(1, barcode[0]);
			ResultSet rs = pstmt.executeQuery();
			if (rs.next())
				M_Product_ID = rs.getInt(1);
			rs.close();
			pstmt.close();
			if (M_Product_ID == 0)
				result = Msg.getMsg(Env.getCtx(), "not.found");
		} catch (SQLException e) {
			log.log(Level.SEVERE, sql.toString(), e);
			result = Msg.getMsg(Env.getCtx(), "not.found");
		}
		if (result.length() != 0)
			return result;
		//Get data via vector find
		//int idxdata = dataPN.indexOf(barcode[0]);		
		//Get data manual
		int index= findIndex(barcode[0]);		
		if (index<0)
			return "Product not found on this Sales Order";
		
		Vector<Object> line = data.get(index);
		if (line==null) 
				return "Product not found on this Sales Order";
		
		
		MProduct prd = MProduct.get(Env.getCtx(), M_Product_ID);
		if (prd == null)
			return Msg.getMsg(Env.getCtx(), "not.found");		
		//
		//
		if (!confirmPanel.isOKVisible()) {
			barcodetrx = new MBarcodeTrx(Env.getCtx(), 0, trxName);
			barcodetrx.setC_DocType_ID((Integer) docTypeField.getValue());
			barcodetrx.setC_BPartner_ID((Integer) bPartnerField.getValue());
			barcodetrx.setC_Order_ID((Integer) cOrderField.getValue());
			barcodetrx.setIsSOTrx(true);
			barcodetrx.setScanDate(TimeUtil.getServerTime());
			barcodetrx.setM_Locator_ID((Integer) locatorField.getValue());
			barcodetrx.setIsGeneratedToInOut(false);
			//
			if (barcode[1].equalsIgnoreCase(fullCode)) {
				// Full code
				isEceran.setSelected(false);
				C_Uom_ID = Env.getContextAsInt(Env.getCtx(),
						"#Def_Package_UOM_ID");				
			} else if  (barcode[1].endsWith(retailCode)) { // retail
				isEceran.setSelected(true);
				C_Uom_ID = Env.getContextAsInt(Env.getCtx(),
					 	"#Def_Package_Inner_UOM_ID");
			}
			if (C_Uom_ID==0)
				return "Default UOM not set!";
			barcodetrx.setIsEceran(isEceran.isSelected());
			barcodetrx.save();
			enableHeader(false);
			//
		}
		String curCode=(isEceran.isSelected()?retailCode:fullCode);
		if(!barcode[1].equalsIgnoreCase(curCode)){ //jika scan ganti tipe
			return "This transaction is for " + (isEceran.isSelected()?"Retail":"Full pack");
		}
		//Insert line
		MBarcodeTrxLine barcodeLine = new MBarcodeTrxLine(Env.getCtx(), 0,
				barcodetrx.getM_BarcodeTrx_ID(), trxName);
		barcodeLine.setC_UOM_ID(C_Uom_ID);
		barcodeLine.setQty(Env.ONE); // Selalu 1
		barcodeLine.setM_Product_ID(M_Product_ID);
		barcodeLine.setC_OrderLine_ID((Integer) dataTable.getModel().getValueAt(index, 6));//get SO Line
		barcodeLine.save();
		
		//
		BigDecimal convertedqty= MUOMConversion.convertProductFrom (Env.getCtx(),M_Product_ID, C_Uom_ID, Env.ONE);
		if (convertedqty==null)
			return "UOM Conversion from " + MUOM.get(Env.getCtx(), C_Uom_ID).getUOMSymbol()  + " to " + prd.getUOMSymbol() + " not found for this item.";
				
		//update method 1 (vector operation)
		//updateData(line, index, convertedqty.doubleValue());
		//Update method 2 (direct table set value)				
		updateData(index,convertedqty.doubleValue());
		infoInserted.setText("Scanned");
		return result;
	}

	/**
	 * Enable/Disable header control
	 * @param enabled
	 */
	private void enableHeader(boolean enabled){	
		locatorField.setReadWrite(enabled);
		bPartnerField.setReadWrite(enabled);
		docTypeField.setReadWrite(enabled);
		cOrderField.setReadWrite(enabled);
		//
		confirmPanel.setOKVisible(!enabled);
		
	}
	
	/**
	 * Add data to vectore as row
	 * @param PartNumber
	 * @param MProductID
	 * @param ProductName
	 * @param UomID
	 * @param UomCode
	 * @param qty, in unit uom/inventory uom
	 * @param scanned qty
	 * @param remain qty to scan
	 */
	private void addData(String PartNumber, int MProductID, String ProductName, int UomID, String UomCode,
			double qty, double scanned, double remain, int OrderLineID) {
		Vector<Object> line = new Vector<Object>(4);
		line.add(PartNumber); // 0-PartNumber
		KeyNamePair pp = new KeyNamePair(MProductID, ProductName);
		line.add(pp); // 1-Product and Name
		line.add(qty); // 2-Qty
		pp = new KeyNamePair(UomID, UomCode);
		line.add(pp); // 3-UOM
		line.add(scanned); // 4-Scanned
		line.add(remain); // 5-Remain
		line.add(OrderLineID); // 6-SO
		data.add(line);
		dataPN.add(PartNumber); //insert part number di list
	    totalLines++;
	}
	
	/**
	 * Update vector data. Manual vector update
	 * @param line current vector line/row
	 * @param index current index line/row
	 * @param scanned qty scanned in Product base UOM/ Inventory UOM
	 */
	private void updateData(Vector<Object> line, int index, double scanned) {		
		double remain = (Double) line.get(5)-scanned; //5-Remain
		if (remain<0){
			ADialog.warn(p_WindowNo, this,"", "Qty remain = 0. Check shipment later.");			
		}
		scanned+= (Double) line.get(4); //4-Scanned
		//
		//modif scanned dan remain
		line.remove(4);
		line.add(4, scanned);
		line.remove(5);
		line.add(remain);
		//remove row
		data.remove(index);
		//add updated row
		data.add(index, line);
		loadTableOIS(data);
	    dataTable.getSelectionModel().setSelectionInterval(index, index);
	}
	
	/**
	 * UPdate data method 2. Direct update grid
	 * @param index
	 * @param scanned
	 */
	private void updateData(int index, double scanned) {
		TableModel tmpData= dataTable.getModel();
		double remain = (Double) tmpData.getValueAt(index, 5) -  scanned; //5-Remain
		if (remain<0){
			ADialog.warn(p_WindowNo, this,"", "Qty remain = 0. Check shipment later.");			
		}
		scanned+= (Double) tmpData.getValueAt(index, 4); //4-Scanned
		//
		tmpData.setValueAt(scanned, index, 4);
		tmpData.setValueAt(remain, index, 5);
		try{
			dataTable.scrollRectToVisible(dataTable.getCellRect(index, 0, true));
		}catch(Exception ex){
			System.out.println(ex.getMessage());
		}
		
	    dataTable.getSelectionModel().setSelectionInterval(index, index);
	    
	}
	
	private void loadOrderLines(int C_Order_ID)
	{
		String sql=	"SELECT ordl.c_orderline_id, ordl.m_product_id, prd.name, prd.upc, " +
						"ordl.c_uom_id, uom.uomsymbol, ordl.qtyordered, ordl.qtyreserved, ordl.qtydelivered " +
				"FROM c_orderline ordl " +
				"INNER JOIN m_product prd on ordl.m_product_id=prd.m_product_id " +
				"INNER JOIN c_uom uom on ordl.c_uom_id=uom.c_uom_id " +
				"WHERE ordl.c_order_id=? AND ordl.qtyreserved<>0 " +
				"ORDER BY ordl.line ";
		try {
			PreparedStatement pstmt = DB.prepareStatement(sql, null);
			pstmt.setInt(1, C_Order_ID);
			ResultSet rs = pstmt.executeQuery();
			statusBar.setStatusLine("Loading...");
			data.clear();		
			while (rs.next()){
				
				addData(rs.getString("upc"), 
						rs.getInt("m_product_id"),
						rs.getString("name"),
						rs.getInt("c_uom_id"),
						rs.getString("uomsymbol"),						 
						rs.getDouble("qtyreserved"), 
						0.0, 
						rs.getDouble("qtyreserved"),
						rs.getInt("c_orderline_id"));
				statusBar.invalidate();
			}
			loadTableOIS(data);
			statusBar.setStatusLine("Ready " + data.size() + " lines");
			rs.close();
			pstmt.close();			
		} catch (SQLException e) {
			log.log(Level.SEVERE, sql.toString(), e);			
		}
	}
	
	/**
	 * Find data index manual
	 * @param upc
	 * @return
	 */
	private int findIndex(String upc){
		int idx=0; //UPC
		for(int i=0;i<dataTable.getRowCount();i++){			
			if (dataTable.getModel().getValueAt(i, idx).equals(upc)){
				return i;
			}
		}
		return -1;
	}
	
	/**
	 * Load data to mini table
	 * @param data
	 */
	protected void loadTableOIS(Vector<Vector<Object>> data) {
		//  Header Info
		    Vector<String> columnNames = new Vector<String>(4);
		    columnNames.add("UPC");
		    columnNames.add(Msg.translate(Env.getCtx(), "M_Product_ID"));		    
		    columnNames.add(Msg.translate(Env.getCtx(), "Quantity"));		    
		    columnNames.add("UOM");
		    columnNames.add("Scanned");
		    columnNames.add("Remain");
		    columnNames.add("OrderLineID");
		    
		    //  Remove previous listeners
		    //dataTable.getModel().removeTableModelListener(this);
		    //  Set Model
		    DefaultTableModel model = new DefaultTableModel(data, columnNames);		   
		    //model.addTableModelListener(this);
		    dataTable.setModel(model);
		    dataTable.setRowSelectionAllowed(true);
		    //		    
		    dataTable.setColumnClass(0, String.class, true);        //  1-VendorProductNo
		    dataTable.setColumnClass(1, String.class, true);        //  2-Product
		    dataTable.setColumnClass(2, Double.class, true);        //  3-Qty
		    dataTable.setColumnClass(3, String.class, true);        //  3-UOm
		    dataTable.setColumnClass(4, Double.class, true);        //  4-Scanned
		    dataTable.setColumnClass(5, Double.class, true);        //  5-Remain
		    dataTable.setColumnClass(6, Integer.class, true);        //  6-SO Line
		    dataTable.setColumnVisibility(dataTable.getColumn("OrderLineID"), false);
		     
		    dataTable.autoSize();
		    
		    
		    
		    //dataTable.se
		}
	
}


